//
//  KLPeerRemote.m
//  WebRTCDemo_iOS
//
//  Created by szblsx2 on 2020/3/5.
//  Copyright © 2020 szblsx2. All rights reserved.
//

#import "KLPeerRemote.h"
#import "KLClient.h"

@interface KLPeerRemote ()<RTCPeerConnectionDelegate>
//连接对象
@property (nonatomic, strong) RTCPeerConnection *mPeerConnection;
//工厂对象(上行传入)
@property (nonatomic, weak) RTCPeerConnectionFactory *mPeerConnectionFactory;
//信令对象(上行传入)
@property (nonatomic, weak) KLClient *mKLClient;
//ice服务器地址(上行传入)
@property (nonatomic, weak) NSArray <RTCIceServer *> *iceServers;

@end

@implementation KLPeerRemote

/**初始化PeerRemote*/
- (instancetype)initWithClient:(KLClient *)client
                       factory:(RTCPeerConnectionFactory *)factory
                    iceServers:(NSArray<RTCIceServer *> *)iceServers
{
    if (self = [super init]) {
        _mKLClient = client;
        _mPeerConnectionFactory = factory;
        _iceServers = iceServers;
        _roomId = @"";
        _subId = @"";
    }
    return self;
}

/**创建PeerConnection*/
- (void)initPeerConnection
{
    [self freePeerConnection];
    // 创建RTCPeerConnection
    RTCConfiguration *configuration = [[RTCConfiguration alloc] init];
    configuration.iceServers = self.iceServers;
    configuration.disableIPV6 = YES;
    configuration.activeResetSrtpParams = YES;
    configuration.sdpSemantics = RTCSdpSemanticsUnifiedPlan;
    configuration.bundlePolicy = RTCBundlePolicyMaxBundle;
    configuration.tcpCandidatePolicy = RTCTcpCandidatePolicyDisabled;
    self.mPeerConnection = [self.mPeerConnectionFactory peerConnectionWithConfiguration:configuration constraints:[self defaultConstraint] delegate:self];
}

/**删除PeerConnection*/
- (void)freePeerConnection
{
    if (_mPeerConnection) {
        [_mPeerConnection close];
        _mPeerConnection = nil;
    }
}

/**创建offer SDP 发送信令订阅流*/
- (void)createOffer
{
    if (!_mPeerConnection) {
        return;
    }
    
    [_mPeerConnection offerForConstraints:[self defaultConstraint] completionHandler:^(RTCSessionDescription * _Nullable sdp, NSError * _Nullable error) {
        if (error) {
            NSLog(@"creatOffer error : %@",error);
            return;
        }
        __weak __typeof(self) ws = self;
        [self->_mPeerConnection setLocalDescription:sdp completionHandler:^(NSError * _Nullable error) {
            if (error) {
                NSLog(@"setLocal error : %@",error);
                return;
            }
            // 发送subscribe到信令服务器
            [ws.mKLClient sendSubscribe:ws.roomId mid:ws.streamId sdp:ws.mPeerConnection.localDescription.sdp];
        }];
    }];
}

/**接收到远端answer SDP处理*/
- (void)onRemoteDescription:(RTCSessionDescription *)sessionDescription
{
    [self.mPeerConnection setRemoteDescription:sessionDescription completionHandler:^(NSError * _Nullable error) {
        if (error) {
            NSLog(@"对端setRemoteDescription error %@",error);
        }else{
            NSLog(@"对端setRemoteDescription success");
        }
    }];
}


/**从服务器取消订阅流*/
- (void)sendUnSubscribe
{
    if (self.subId.length == 0) {
        return;
    }
    [self.mKLClient sendUnsubscribe:self.roomId mid:self.subId];
    self.subId = @"";
}


#pragma mark - RTCPeerConnectionDelegate

- (void)peerConnection:(RTCPeerConnection *)peerConnection didChangeSignalingState:(RTCSignalingState)stateChanged
{
    NSLog(@"");
}

/**获取到远程音视频流回调*/
- (void)peerConnection:(RTCPeerConnection *)peerConnection didAddStream:(RTCMediaStream *)stream
{
    NSLog(@"收到远端音频track%zd条",stream.audioTracks.count);
    NSLog(@"收到远端视频track%zd条",stream.videoTracks.count);
    dispatch_async(dispatch_get_main_queue(), ^{
        //设置默认扬声器播放音频
        if (self->_openSpeaker) {
            [[UIDevice currentDevice] setProximityMonitoringEnabled:NO];
            [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
        }
        if (stream.videoTracks.count > 0 || stream.audioTracks.count > 0) {
            if (self.delegate && [self.delegate respondsToSelector:@selector(klPeerRemote:addRemoteStream:streamId:userId:)]) {
                [self.delegate klPeerRemote:self addRemoteStream:stream streamId:self.streamId userId:self.userId];
            }
        }
    });
}

- (void)peerConnection:(RTCPeerConnection *)peerConnection didRemoveStream:(RTCMediaStream *)stream
{
    NSLog(@"");
}

- (void)peerConnectionShouldNegotiate:(RTCPeerConnection *)peerConnection
{
    NSLog(@"");
}

- (void)peerConnection:(RTCPeerConnection *)peerConnection didChangeIceConnectionState:(RTCIceConnectionState)newState
{
    NSLog(@"");
}

/**ICEcandidate收集状态变化*/
- (void)peerConnection:(RTCPeerConnection *)peerConnection didChangeIceGatheringState:(RTCIceGatheringState)newState
{
    if (newState == RTCIceGatheringStateComplete) {
        NSLog(@"IceCandidate收集完成");
    }
}

/**获取到新的ICEcandidate*/
- (void)peerConnection:(RTCPeerConnection *)peerConnection didGenerateIceCandidate:(RTCIceCandidate *)candidate
{
    NSLog(@"IceCandidate收集 : %@",candidate.sdp);
    [self sendLocalIceCandidate:candidate];
}

- (void)peerConnection:(RTCPeerConnection *)peerConnection didRemoveIceCandidates:(NSArray<RTCIceCandidate *> *)candidates
{
    NSLog(@"");
}

- (void)peerConnection:(RTCPeerConnection *)peerConnection didOpenDataChannel:(RTCDataChannel *)dataChannel
{
    NSLog(@"");
}

#pragma mark - Private Method

/**媒体描述约束*/
- (RTCMediaConstraints *)defaultConstraint
{
    NSLog(@"");
    NSDictionary *mandatory = @{kRTCMediaConstraintsOfferToReceiveAudio : kRTCMediaConstraintsValueTrue,
                                kRTCMediaConstraintsOfferToReceiveVideo : kRTCMediaConstraintsValueTrue};
    RTCMediaConstraints *constraints = [[RTCMediaConstraints alloc] initWithMandatoryConstraints:mandatory optionalConstraints:nil];
    return constraints;
}

/**发送ICE给信令服务器*/
- (void)sendLocalIceCandidate:(RTCIceCandidate *)candidate
{
    NSDictionary *dic = @{@"candidate":@{@"type":@"candidate",@"label":@(candidate.sdpMLineIndex),@"id":candidate.sdpMid,@"candidate":candidate.sdp}};
    [self.mKLClient sendIceCandidate:self.roomId mid: self.streamId object:dic bPub:false];
}


#pragma mark - Getter



@end
